package rs.pnv.config;

import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp2.BasicDataSource;
import org.hibernate.jpa.HibernatePersistenceProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.JstlView;
import org.springframework.web.servlet.view.UrlBasedViewResolver;

@Configuration
@ComponentScan({ "rs.pnv" })
@EnableWebMvc
@EnableJpaRepositories("rs.pnv.repository")
@PropertySource({ "classpath:database.properties" })
public class SepMerchantConfiguration extends WebMvcConfigurerAdapter {

	@Autowired
	private Environment env;

	private static final String VIEW_RESOLVER_PREFIX = "view.resolver.prefix";
	private static final String VIEW_RESOLVER_SUFFIX = "view.resolver.sufix";

	private static final String MODEL_PACKAGE = "model.package";
	private static final String MESSAGE_PROPERTIES_FILE_NAME = "message.properties.file.name";

	private static final String JDBC_DRIVER_CLASS_NAME = "jdbc.driverClassName";
	private static final String JDBC_URL = "jdbc.url";
	private static final String JDBC_USER = "jdbc.user";
	private static final String JDBC_PASS = "jdbc.pass";

	private static final String HIBERNATE_HBM2DDL_AUTO = "hibernate.hbm2ddl.auto";
	private static final String HIBERNATE_DIALECT = "hibernate.dialect";
	private static final String HIBERNATE_SHOW_SQL = "hibernate.show_sql";
	private static final String HIBERNATE_FORMAT_SQL = "hibernate.format_sql";
	private static final String HIBERNATE_NAMING_STRATEGY = "hibernate.ejb.naming_strategy";
	private static final String HIBERNATE_IMPORT_FILES = "hibernate.hbm2ddl.import_files";

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
		registry.addResourceHandler("/css/**").addResourceLocations("/css/");
		registry.addResourceHandler("/images/**").addResourceLocations("/images/");
		registry.addResourceHandler("/js/**").addResourceLocations("/js/");
		registry.addResourceHandler("/fonts/**").addResourceLocations("/fonts/");
	}

	@Bean
	public UrlBasedViewResolver urlBaseViewResolver() {
		UrlBasedViewResolver resolver = new UrlBasedViewResolver();

		resolver.setPrefix(env.getProperty(VIEW_RESOLVER_PREFIX));
		resolver.setSuffix(env.getProperty(VIEW_RESOLVER_SUFFIX));
		resolver.setViewClass(JstlView.class);

		return resolver;
	}

	@Bean
	public DataSource dataSource() {
		BasicDataSource dataSource = new BasicDataSource();

		dataSource.setDriverClassName(env.getProperty(JDBC_DRIVER_CLASS_NAME));
		dataSource.setUrl(env.getProperty(JDBC_URL));
		dataSource.setUsername(env.getProperty(JDBC_USER));
		dataSource.setPassword(env.getProperty(JDBC_PASS));

		return dataSource;
	}

	@Bean
	public JpaTransactionManager transactionManager() {
		JpaTransactionManager txManager = new JpaTransactionManager();

		txManager.setEntityManagerFactory(entityManagerFactory().getObject());

		return txManager;
	}

	@Bean
	public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
		LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();

		entityManagerFactory.setDataSource(dataSource());
		entityManagerFactory.setPackagesToScan(env.getProperty(MODEL_PACKAGE));
		entityManagerFactory.setPersistenceProviderClass(HibernatePersistenceProvider.class);
		entityManagerFactory.setJpaProperties(jpaProperties());

		return entityManagerFactory;
	}

	@Bean
	public ResourceBundleMessageSource messageSource() {
		ResourceBundleMessageSource resourceBundleMessageSource = new ResourceBundleMessageSource();

		resourceBundleMessageSource.setBasename(env.getProperty(MESSAGE_PROPERTIES_FILE_NAME));

		return resourceBundleMessageSource;
	}

	public Properties jpaProperties() {
		Properties jpaProperties = new Properties();

		jpaProperties.setProperty(HIBERNATE_DIALECT, env.getProperty(HIBERNATE_DIALECT));
		jpaProperties.setProperty(HIBERNATE_HBM2DDL_AUTO, env.getProperty(HIBERNATE_HBM2DDL_AUTO));
		jpaProperties.setProperty(HIBERNATE_SHOW_SQL, env.getProperty(HIBERNATE_SHOW_SQL));
		jpaProperties.setProperty(HIBERNATE_FORMAT_SQL, env.getProperty(HIBERNATE_FORMAT_SQL));
		jpaProperties.setProperty(HIBERNATE_NAMING_STRATEGY, env.getProperty(HIBERNATE_NAMING_STRATEGY));
		jpaProperties.setProperty(HIBERNATE_IMPORT_FILES, env.getProperty(HIBERNATE_IMPORT_FILES));

		return jpaProperties;
	}

}
